<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use App\depository\ApiLogDep;
use App\depository\SubApiLogDep;

class AdminApiLog
{
    /**
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
     */
    public function handle(Request $request, Closure $next)
    {
        $noArr = [
            '/api/log/list',
            '/api/log/selfList',
            '/api/user/permissions',
            '/api/cfg/edit',
            '/api/cfg/add',
            '/api/sub/cfg/add',
            '/api/sub/cfg/edit',
            '/api/manageplayer/add',
            '/api/fly/add',
            '/api/killrecord/add',
            '/api/teamrecord/add',
            '/api/bunkorecord/add',
            '/api/talkrecord/add',
            '/api/playrecord/add',
            '/api/friendkillrecord/add',
            '/api/managesecret/add',
            '/api/manageforbidden/add',
            '/api/managecmd/add',
            '/api/manageplayer/get',
            '/api/sub/log/list',
            '/api/sub/log/selfList',
            '/api/team/server/add',
            '/api/user/init',
            '/api/role/init',
            '/api/team/init',
            '/api/map/init',
            '/api/cfg/init',
            '/api/permission/init',
            '/api/sub/user/permissions',
            '/api/sub/user/init',
            '/api/sub/gamer/init',
            '/api/sub/map/init',
            '/api/sub/authority/init',
            '/api/sub/secret/init',
            '/api/sub/active/init',
            '/api/sub/forbidden/init',
            '/api/sub/team/detail/init',
            '/api/sub/cfg/init',
            '/api/permission/sub/init',
            '/api/sub/code/init',
            '/api/sub/role/init',

            '/api/record/fly/init',
            '/api/record/kill/init',
            '/api/record/team/init',
            '/api/record/bunko/init',
            '/api/record/talk/init',
            '/api/record/friendkill/init',
            '/api/record/player/init',
            '/api/notice/info',
            '/api/user/trade',

            '/api/system/get',
            '/api/sub/gamer/list'
        ];

        if (!in_array($method = $request->getMethod(), ['GET', 'OPTIONS']) && !in_array($request->getPathInfo(), $noArr)) {
            $teamId = $request->headers->get('TeamId');
            if(!$teamId) {
                $logDep = new ApiLogDep();
                $data = [
                    'user_id' => $request->user() ? $request->user()->id : '-1',
                    'path' => $request->getPathInfo(),
                    'method' => $method,
                    'ip' => $this->get_client_ip(),
                    'input' => json_encode($request->all()),
                ];
                $logDep->add($data);
            }else{
                $logDep = new SubApiLogDep();
                $data = [
                    'user_id' => $request->user() ? $request->user()->id : '-1',
                    'team_id' => $teamId,
                    'path' => $request->getPathInfo(),
                    'method' => $method,
                    'ip' => $this->get_client_ip(),
                    'input' => json_encode($request->all()),
                ];
                $logDep->add($data);
            }
        }
        return $next($request);
    }


    function get_client_ip() {
        // 首先尝试直接连接的客户端IP
        $client_ip = $_SERVER['REMOTE_ADDR'];

        // 检查HTTP_X_FORWARDED_FOR头，它可能包含通过代理的IP
        if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            // 处理逗号分隔的IP列表，获取最左侧的IP
            $forwarded_ips = preg_split('/,\s*/', $_SERVER['HTTP_X_FORWARDED_FOR']);
            $client_ip = trim($forwarded_ips[0]);

            // 如果看起来像一个私有IP地址（内部网络），则使用REMOTE_ADDR
            // 私有IP范围参考：https://tools.ietf.org/html/rfc1918
            if (filter_var($client_ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
                // 如果是有效的公共IP，我们就认为这是真实的IP
                // 否则，可能是伪造的，我们仍然使用REMOTE_ADDR
                $is_public_ip = true;
            } else {
                $is_public_ip = false;
            }

            if (!$is_public_ip) {
                $client_ip = $_SERVER['REMOTE_ADDR'];
            }
        }

        // 返回最终确定的IP地址
        return $client_ip;
    }
}
